home *** CD-ROM | disk | FTP | other *** search
/ Windows Game Programming for Dummies (2nd Edition) / WinGamProgFD.iso / mac / DirectX SDK / DXSDK / samples / Multimedia / Direct3D / MFCFog / fog.cpp < prev    next >
C/C++ Source or Header  |  2001-10-31  |  37KB  |  1,056 lines

  1. //-----------------------------------------------------------------------------
  2. // File: Fog.cpp
  3. //
  4. // Desc: Example code showing how to do fog in D3D
  5. //
  6. // Copyright (c) 1997-2001 Microsoft Corporation. All rights reserved.
  7. //-----------------------------------------------------------------------------
  8. #define STRICT
  9. #include "stdafx.h"
  10. #include <tchar.h>
  11. #include <math.h>
  12. #include <D3DX8.h>
  13. #include "resource.h"
  14. #include "D3DApp.h"
  15. #include "D3DUtil.h"
  16. #include "DXUtil.h"
  17. #include "fog.h"
  18.  
  19.  
  20.  
  21.  
  22. //-----------------------------------------------------------------------------
  23. // Structures and Macros
  24. //-----------------------------------------------------------------------------
  25. inline DWORD FtoDW( FLOAT f ) { return *((DWORD*)&f); }
  26.  
  27. struct FOGVERTEX
  28. {
  29.         D3DXVECTOR3 p;
  30.         D3DXVECTOR3 n;
  31.         FLOAT       tu, tv;
  32. };
  33.  
  34. #define D3DFVF_FOGVERTEX (D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1)
  35.  
  36. #define FAR_PLANE (150.0f)
  37. #define NEAR_PLANE (1.0f)
  38.  
  39.  
  40.  
  41.  
  42. //-----------------------------------------------------------------------------
  43. // Application globals
  44. //-----------------------------------------------------------------------------
  45. TCHAR*        g_strAppTitle       = _T( "MFCFog: D3D Fog Sample Using MFC" );
  46. CApp          g_App;
  47. CAppForm*     g_AppFormView = NULL;
  48.  
  49.  
  50.  
  51.  
  52. //-----------------------------------------------------------------------------
  53. // The MFC macros are all listed here
  54. //-----------------------------------------------------------------------------
  55. IMPLEMENT_DYNCREATE( CAppDoc,      CDocument )
  56. IMPLEMENT_DYNCREATE( CAppFrameWnd, CFrameWnd )
  57. IMPLEMENT_DYNCREATE( CAppForm,     CFormView )
  58.  
  59.  
  60.  
  61.  
  62. BEGIN_MESSAGE_MAP( CApp, CWinApp )
  63.     //{{AFX_MSG_MAP(CApp)
  64.     //}}AFX_MSG_MAP
  65. END_MESSAGE_MAP()
  66.  
  67.  
  68.  
  69.  
  70. BEGIN_MESSAGE_MAP( CAppForm, CFormView )
  71.     //{{AFX_MSG_MAP(CAppForm)
  72.     ON_COMMAND(    IDC_VIEWFULLSCREEN, OnToggleFullScreen )
  73.     ON_COMMAND(    IDM_CHANGEDEVICE,   OnChangeDevice )
  74.     ON_WM_HSCROLL()
  75.     ON_BN_CLICKED( IDC_FOGCOLOR,       OnFogColor )
  76.     ON_BN_CLICKED( IDC_RANGEBASEDFOG,  OnRangeBasedFog )
  77.     ON_BN_CLICKED( IDC_VERTEXFOG,      OnVertexFog )
  78.     ON_BN_CLICKED( IDC_TABLEFOG,       OnTableFog )
  79.     ON_BN_CLICKED( IDC_LINEARFOGMODE,  OnFogMode )
  80.     ON_BN_CLICKED( IDC_LORESTERRAIN,   OnTerrainResolution)
  81.     ON_BN_CLICKED( IDM_CHANGEDEVICE,   OnChangeDevice )
  82.     ON_BN_CLICKED( IDC_EXPFOGMODE,     OnFogMode )
  83.     ON_BN_CLICKED( IDC_EXP2FOGMODE,    OnFogMode )
  84.     ON_BN_CLICKED( IDC_HIRESTERRAIN,   OnTerrainResolution)
  85.     //}}AFX_MSG_MAP
  86. END_MESSAGE_MAP()
  87.  
  88.  
  89.  
  90.  
  91. BEGIN_MESSAGE_MAP(CAppDoc, CDocument)
  92.     //{{AFX_MSG_MAP(CAppDoc)
  93.         // NOTE - the ClassWizard will add and remove mapping macros here.
  94.         //    DO NOT EDIT what you see in these blocks of generated code!
  95.     //}}AFX_MSG_MAP
  96. END_MESSAGE_MAP()
  97.  
  98.  
  99.  
  100.  
  101. BEGIN_MESSAGE_MAP(CAppFrameWnd, CFrameWnd)
  102.     //{{AFX_MSG_MAP(CAppFrameWnd)
  103.     //}}AFX_MSG_MAP
  104. END_MESSAGE_MAP()
  105.  
  106.  
  107.  
  108.  
  109. //-----------------------------------------------------------------------------
  110. // Name: InitInstance()
  111. // Desc: This is the main entry point for the application. The MFC window stuff
  112. //       is initialized here. See also the main initialization routine for the
  113. //       CAppForm class, which is called indirectly from here.
  114. //-----------------------------------------------------------------------------
  115. BOOL CApp::InitInstance()
  116. {
  117.     // Asscociate the MFC app with the frame window and doc/view classes
  118.     AddDocTemplate( new CSingleDocTemplate( IDR_MAINFRAME,
  119.                                             RUNTIME_CLASS(CAppDoc),
  120.                                             RUNTIME_CLASS(CAppFrameWnd),
  121.                                             RUNTIME_CLASS(CAppForm) ) );
  122.  
  123.     // Dispatch commands specified on the command line (req'd by MFC). This
  124.     // also initializes the the CAppDoc, CAppFrameWnd, and CAppForm classes.
  125.     CCommandLineInfo cmdInfo;
  126.     ParseCommandLine( cmdInfo );
  127.     if( !ProcessShellCommand( cmdInfo ) )
  128.         return FALSE;
  129.  
  130.     if( !g_AppFormView->IsReady() )
  131.         return FALSE;
  132.  
  133.     g_AppFormView->GetParentFrame()->RecalcLayout();
  134.     g_AppFormView->ResizeParentToFit( FALSE );   
  135.  
  136.     m_pMainWnd->SetWindowText( g_strAppTitle );
  137.     m_pMainWnd->UpdateWindow();
  138.  
  139.     return TRUE;
  140. }
  141.  
  142.  
  143.  
  144.  
  145. //-----------------------------------------------------------------------------
  146. // Name: OnIdle()
  147. // Desc: Uses idle time to render the 3D scene.
  148. //-----------------------------------------------------------------------------
  149. BOOL CApp::OnIdle( LONG )
  150. {
  151.     // Do not render if the app is minimized
  152.     if( m_pMainWnd->IsIconic() )
  153.         return FALSE;
  154.  
  155.     TCHAR strStatsPrev[200];
  156.  
  157.     lstrcpy(strStatsPrev, g_AppFormView->PstrFrameStats());
  158.  
  159.     // Update and render a frame
  160.     if( g_AppFormView->IsReady() )
  161.     {
  162.         g_AppFormView->CheckForLostFullscreen();
  163.         g_AppFormView->RenderScene();
  164.         if (lstrcmp(strStatsPrev, g_AppFormView->PstrFrameStats()) != 0)
  165.             g_AppFormView->GetDlgItem(IDC_FPS_TEXT)->SetWindowText(g_AppFormView->PstrFrameStats());
  166.     }
  167.  
  168.     // Keep requesting more idle time
  169.     return TRUE;
  170. }
  171.  
  172.  
  173.  
  174.  
  175. //-----------------------------------------------------------------------------
  176. // Name: PreCreateWindow()
  177. // Desc: Change the window style (so it cannot maximize or be sized) before
  178. //       the main frame window is created.
  179. //-----------------------------------------------------------------------------
  180. BOOL CAppFrameWnd::PreCreateWindow( CREATESTRUCT& cs )
  181. {
  182.     cs.style = WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX;
  183.  
  184.     return CFrameWnd::PreCreateWindow( cs );
  185. }
  186.  
  187.  
  188.  
  189.  
  190. //-----------------------------------------------------------------------------
  191. // Name: CAppForm()
  192. // Desc: Constructor for the dialog resource form
  193. //-----------------------------------------------------------------------------
  194. CAppForm::CAppForm()
  195.          :CFormView( IDD_FORMVIEW )
  196. {
  197.     g_AppFormView          = this;
  198.     m_bHiResTerrain        = FALSE;
  199.     m_bHiResTerrainOld     = FALSE;
  200.     m_dwFogColor           = 0x00b5b5ff;
  201.     m_dwFogMode            = D3DFOG_LINEAR;
  202.     m_bCanDoTableFog       = FALSE;
  203.     m_bCanDoVertexFog      = FALSE;
  204.     m_bCanDoWFog           = FALSE;
  205.     m_bDeviceUsesWFog      = FALSE;
  206.     m_bRangeBasedFog       = FALSE;
  207.     m_bUsingTableFog       = FALSE;
  208.     m_fFogStartSlider      = 0.0f;
  209.     m_fFogEndSlider        = 1.0f;
  210.     m_fFogStartValue       = 0.0f;
  211.     m_fFogEndValue         = 1.0f;
  212.     m_fFogDensity          = 0.0f;
  213.     m_hwndRenderWindow     = NULL;
  214.     m_hwndRenderFullScreen = NULL;
  215.     m_pFloorTexture        = NULL;
  216.     m_pTerrainVB           = NULL;
  217.     m_dwNumTerrainVertices = 0L;
  218.     m_pColumnVB            = NULL;
  219.     m_dwNumColumnVertices  = 0L;
  220.  
  221.     // Override some CD3DApplication defaults:
  222.     m_bUseDepthBuffer      = TRUE;
  223. }
  224.  
  225.  
  226.  
  227.  
  228. //-----------------------------------------------------------------------------
  229. // Name: ~CAppForm()
  230. // Desc: Destructor for the dialog resource form. Shuts down the app
  231. //-----------------------------------------------------------------------------
  232. CAppForm::~CAppForm()
  233. {
  234.     Cleanup3DEnvironment();
  235. }
  236.  
  237.  
  238.  
  239.  
  240. //-----------------------------------------------------------------------------
  241. // Name: OnToggleFullScreen()
  242. // Desc: Called when user toggles the fullscreen mode
  243. //-----------------------------------------------------------------------------
  244. void CAppForm::OnToggleFullScreen()
  245. {
  246.     ToggleFullscreen();
  247. }
  248.  
  249.  
  250.  
  251.  
  252. //-----------------------------------------------------------------------------
  253. // Name: OnChangeDevice()
  254. // Desc: Use hit the "Change Device.." button. Display the dialog for the user
  255. //       to select a new device/mode, and call Change3DEnvironment to
  256. //       use the new device/mode.
  257. //-----------------------------------------------------------------------------
  258. VOID CAppForm::OnChangeDevice()
  259. {
  260.     UserSelectNewDevice();
  261.  
  262.     // Update UI, and device's fog parameters
  263.     UpdateUIForDeviceCapabilites();
  264.     SetFogParameters();
  265. }
  266.  
  267.  
  268.  
  269.  
  270. //-----------------------------------------------------------------------------
  271. // Name: AdjustWindowForChange()
  272. // Desc: Adjusts the window properties for windowed or fullscreen mode
  273. //-----------------------------------------------------------------------------
  274. HRESULT CAppForm::AdjustWindowForChange()
  275. {
  276.     if( m_bWindowed )
  277.     {
  278.         ::ShowWindow( m_hwndRenderFullScreen, SW_HIDE );
  279.         CD3DApplication::m_hWnd = m_hwndRenderWindow;
  280.     }
  281.     else
  282.     {
  283.         if( ::IsIconic( m_hwndRenderFullScreen ) )
  284.             ::ShowWindow( m_hwndRenderFullScreen, SW_RESTORE );
  285.         ::ShowWindow( m_hwndRenderFullScreen, SW_SHOW );
  286.         CD3DApplication::m_hWnd = m_hwndRenderFullScreen;
  287.     }
  288.     return S_OK;
  289. }
  290.  
  291.  
  292.  
  293.  
  294. //-----------------------------------------------------------------------------
  295. // Name: FullScreenWndProc()
  296. // Desc: The WndProc funtion used when the app is in fullscreen mode. This is
  297. //       needed simply to trap the ESC key.
  298. //-----------------------------------------------------------------------------
  299. LRESULT CALLBACK FullScreenWndProc( HWND hWnd, UINT msg, WPARAM wParam,
  300.                                     LPARAM lParam )
  301. {
  302.     if( msg == WM_CLOSE )
  303.     {
  304.         // User wants to exit, so go back to windowed mode and exit for real
  305.         g_AppFormView->OnToggleFullScreen();
  306.         g_App.GetMainWnd()->PostMessage( WM_CLOSE, 0, 0 );
  307.     }
  308.  
  309.     else if( msg == WM_SETCURSOR )
  310.     {
  311.         SetCursor( NULL );
  312.     }
  313.  
  314.     else if( msg == WM_KEYUP && wParam == VK_ESCAPE )
  315.     {
  316.         // User wants to leave fullscreen mode
  317.         g_AppFormView->OnToggleFullScreen();
  318.     }
  319.     return DefWindowProc( hWnd, msg, wParam, lParam );
  320. }
  321.  
  322.  
  323.  
  324.  
  325. //-----------------------------------------------------------------------------
  326. // Name: CheckForLostFullscreen()
  327. // Desc: If fullscreen and device was lost (probably due to alt-tab), 
  328. //       automatically switch to windowed mode
  329. //-----------------------------------------------------------------------------
  330. HRESULT CAppForm::CheckForLostFullscreen()
  331. {
  332.     HRESULT hr;
  333.  
  334.     if( m_bWindowed )
  335.         return S_OK;
  336.  
  337.     if( FAILED( hr = m_pd3dDevice->TestCooperativeLevel() ) )
  338.         ForceWindowed();
  339.  
  340.     return S_OK;
  341. }
  342.  
  343.  
  344.  
  345.  
  346. //-----------------------------------------------------------------------------
  347. // Name: OnTerrainResolution()
  348. // Desc: Called when the user selects the terrain resolution
  349. //-----------------------------------------------------------------------------
  350. VOID CAppForm::OnTerrainResolution()
  351. {
  352.     m_bHiResTerrain = ((CButton*)GetDlgItem(IDC_HIRESTERRAIN))->GetCheck();
  353.  
  354.     SetFogParameters();
  355. }
  356.  
  357.  
  358.  
  359.  
  360. //-----------------------------------------------------------------------------
  361. // Name: OnHScroll()
  362. // Desc: Called when the user moves any scroll bar. Check which scrollbar was
  363. //       moved, and extract the appropiate value to a global variable.
  364. //-----------------------------------------------------------------------------
  365. void CAppForm::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
  366. {
  367.     // Get the new fog parameters
  368.     m_fFogStartSlider = ((CSliderCtrl*)GetDlgItem(IDC_FOGSTART_SLIDER))->GetPos()/100.0f;
  369.     m_fFogEndSlider   = ((CSliderCtrl*)GetDlgItem(IDC_FOGEND_SLIDER))->GetPos()/100.0f;
  370.     m_fFogDensity     = ((CSliderCtrl*)GetDlgItem(IDC_FOGDENSITY_SLIDER))->GetPos()/100.0f;
  371.  
  372.     if( m_fFogEndSlider < m_fFogStartSlider )
  373.     {
  374.         ((CSliderCtrl*)GetDlgItem(IDC_FOGEND_SLIDER))->SetPos((INT)(m_fFogStartSlider*100.0f));
  375.         m_fFogEndSlider = m_fFogStartSlider;
  376.     }
  377.     
  378.     SetFogParameters();
  379.  
  380.     CFormView::OnHScroll(nSBCode, nPos, pScrollBar);
  381. }
  382.  
  383.  
  384.  
  385.  
  386. //-----------------------------------------------------------------------------
  387. // Name: OnFogColor()
  388. // Desc: Called when the user hits the "fog color..." button. Display a color
  389. //       selection dialog box, and set the global fog color variable.
  390. //-----------------------------------------------------------------------------
  391. void CAppForm::OnFogColor()
  392. {
  393.     CColorDialog dlg;
  394.  
  395.     if( IDOK == dlg.DoModal() )
  396.     {
  397.         m_dwFogColor = ((((DWORD)dlg.GetColor())&0x000000ff)<<16) +
  398.                        ((((DWORD)dlg.GetColor())&0x0000ff00)) +
  399.                        ((((DWORD)dlg.GetColor())&0x00ff0000)>>16);
  400.         SetFogParameters();
  401.     }
  402. }
  403.  
  404.  
  405.  
  406.  
  407. //-----------------------------------------------------------------------------
  408. // Name: OnRangeBasedFog()
  409. // Desc: Toggle the boolean variable for whether RangeBasedFog is enabled.
  410. //-----------------------------------------------------------------------------
  411. void CAppForm::OnRangeBasedFog()
  412. {
  413.     m_bRangeBasedFog = ((CButton*)GetDlgItem(IDC_RANGEBASEDFOG))->GetCheck();
  414.  
  415.     SetFogParameters();
  416. }
  417.  
  418.  
  419.  
  420.  
  421. //-----------------------------------------------------------------------------
  422. // Name: OnVertexFog()
  423. // Desc: User selected vertex fog. Upadte the global variables as appropiate.
  424. //-----------------------------------------------------------------------------
  425. void CAppForm::OnVertexFog()
  426. {
  427.     // Note: We always assume range fog is available if doing vertex fog
  428.     GetDlgItem(IDC_RANGEBASEDFOG)->EnableWindow(TRUE);
  429.  
  430.     GetDlgItem(IDC_LINEARFOGMODE)->EnableWindow(TRUE);
  431.     GetDlgItem(IDC_EXPFOGMODE)->EnableWindow(FALSE);
  432.     GetDlgItem(IDC_EXP2FOGMODE)->EnableWindow(FALSE);
  433.     ((CButton*)GetDlgItem(IDC_LINEARFOGMODE))->SetCheck(TRUE);
  434.     ((CButton*)GetDlgItem(IDC_EXPFOGMODE))->SetCheck(FALSE);
  435.     ((CButton*)GetDlgItem(IDC_EXP2FOGMODE))->SetCheck(FALSE);
  436.  
  437.     GetDlgItem(IDC_FOGSTARTMIN_TEXT)->SetWindowText( _T("near (1.0)") );
  438.     GetDlgItem(IDC_FOGSTARTMAX_TEXT)->SetWindowText( _T("far (150.0)") );
  439.     GetDlgItem(IDC_FOGENDMIN_TEXT)->SetWindowText( _T("near (1.0)") );
  440.     GetDlgItem(IDC_FOGENDMAX_TEXT)->SetWindowText( _T("far (150.0)") );
  441.  
  442.     m_bUsingTableFog = FALSE;
  443.     OnFogMode();
  444. }
  445.  
  446.  
  447.  
  448.  
  449. //-----------------------------------------------------------------------------
  450. // Name: OnTableFog()
  451. // Desc: User selected table fog. Upadte the global variables as appropiate.
  452. //-----------------------------------------------------------------------------
  453. void CAppForm::OnTableFog()
  454. {
  455.     // Note: We only assume range fog is available if doing vertex fog
  456.     GetDlgItem(IDC_RANGEBASEDFOG)->EnableWindow(FALSE);
  457.     ((CButton*)GetDlgItem(IDC_RANGEBASEDFOG))->SetCheck(FALSE);
  458.  
  459.     GetDlgItem(IDC_LINEARFOGMODE)->EnableWindow(TRUE);
  460.     GetDlgItem(IDC_EXPFOGMODE)->EnableWindow(TRUE);
  461.     GetDlgItem(IDC_EXP2FOGMODE)->EnableWindow(TRUE);
  462.  
  463.     if( m_bCanDoWFog )
  464.     {
  465.         GetDlgItem(IDC_FOGSTARTMIN_TEXT)->SetWindowText( _T("near (1.0)") );
  466.         GetDlgItem(IDC_FOGSTARTMAX_TEXT)->SetWindowText( _T("far (150.0)") );
  467.         GetDlgItem(IDC_FOGENDMIN_TEXT)->SetWindowText( _T("near (1.0)") );
  468.         GetDlgItem(IDC_FOGENDMAX_TEXT)->SetWindowText( _T("far (150.0)") );
  469.     }
  470.     else
  471.     {
  472.         GetDlgItem(IDC_FOGSTARTMIN_TEXT)->SetWindowText( _T("near (0.0)") );
  473.         GetDlgItem(IDC_FOGSTARTMAX_TEXT)->SetWindowText( _T("far (1.0)") );
  474.         GetDlgItem(IDC_FOGENDMIN_TEXT)->SetWindowText( _T("near (0.0)") );
  475.         GetDlgItem(IDC_FOGENDMAX_TEXT)->SetWindowText( _T("far (1.0)") );
  476.     }
  477.  
  478.     m_bUsingTableFog = TRUE;
  479.     OnFogMode();
  480. }
  481.  
  482.  
  483.  
  484.  
  485. //-----------------------------------------------------------------------------
  486. // Name: OnFogMode()
  487. // Desc: User changed the fog mode. Update the UI and global variables, as many
  488. //       controls are mutually exclusive.
  489. //-----------------------------------------------------------------------------
  490. void CAppForm::OnFogMode()
  491. {
  492.     if( ((CButton*)GetDlgItem(IDC_LINEARFOGMODE))->GetCheck() )
  493.     {
  494.         m_dwFogMode = D3DFOG_LINEAR;
  495.  
  496.         GetDlgItem(IDC_FOGSTART_TEXT)->EnableWindow(TRUE);
  497.         GetDlgItem(IDC_FOGSTARTMIN_TEXT)->EnableWindow(TRUE);
  498.         GetDlgItem(IDC_FOGSTARTMAX_TEXT)->EnableWindow(TRUE);
  499.         GetDlgItem(IDC_FOGSTART_SLIDER)->EnableWindow(TRUE);
  500.         GetDlgItem(IDC_FOGEND_TEXT)->EnableWindow(TRUE);
  501.         GetDlgItem(IDC_FOGENDMIN_TEXT)->EnableWindow(TRUE);
  502.         GetDlgItem(IDC_FOGENDMAX_TEXT)->EnableWindow(TRUE);
  503.         GetDlgItem(IDC_FOGEND_SLIDER)->EnableWindow(TRUE);
  504.         GetDlgItem(IDC_FOGDENSITY_TEXT)->EnableWindow(FALSE);
  505.         GetDlgItem(IDC_FOGDENSITYMIN_TEXT)->EnableWindow(FALSE);
  506.         GetDlgItem(IDC_FOGDENSITYMAX_TEXT)->EnableWindow(FALSE);
  507.         GetDlgItem(IDC_FOGDENSITY_SLIDER)->EnableWindow(FALSE);
  508.     }
  509.     else
  510.     {
  511.         GetDlgItem(IDC_FOGSTART_TEXT)->EnableWindow(FALSE);
  512.         GetDlgItem(IDC_FOGSTARTMIN_TEXT)->EnableWindow(FALSE);
  513.         GetDlgItem(IDC_FOGSTARTMAX_TEXT)->EnableWindow(FALSE);
  514.         GetDlgItem(IDC_FOGSTART_SLIDER)->EnableWindow(FALSE);
  515.         GetDlgItem(IDC_FOGEND_TEXT)->EnableWindow(FALSE);
  516.         GetDlgItem(IDC_FOGENDMIN_TEXT)->EnableWindow(FALSE);
  517.         GetDlgItem(IDC_FOGENDMAX_TEXT)->EnableWindow(FALSE);
  518.         GetDlgItem(IDC_FOGEND_SLIDER)->EnableWindow(FALSE);
  519.         GetDlgItem(IDC_FOGDENSITY_TEXT)->EnableWindow(TRUE);
  520.         GetDlgItem(IDC_FOGDENSITYMIN_TEXT)->EnableWindow(TRUE);
  521.         GetDlgItem(IDC_FOGDENSITYMAX_TEXT)->EnableWindow(TRUE);
  522.         GetDlgItem(IDC_FOGDENSITY_SLIDER)->EnableWindow(TRUE);
  523.  
  524.         if( ((CButton*)GetDlgItem(IDC_EXPFOGMODE))->GetCheck() )
  525.             m_dwFogMode = D3DFOG_EXP;
  526.         if( ((CButton*)GetDlgItem(IDC_EXP2FOGMODE))->GetCheck() )
  527.             m_dwFogMode = D3DFOG_EXP2;
  528.     }
  529.  
  530.     SetFogParameters();
  531. }
  532.  
  533.  
  534.  
  535.  
  536. //-----------------------------------------------------------------------------
  537. // Name: UpdateUIForDeviceCapabilites()
  538. // Desc: Whenever we get a new device, call this function to enable/disable the
  539. //       appropiate UI controls to match the device's capabilities.
  540. //-----------------------------------------------------------------------------
  541. VOID CAppForm::UpdateUIForDeviceCapabilites()
  542. {
  543.     // Check the capabilities of the device
  544.     DWORD dwCaps = m_d3dCaps.RasterCaps;
  545.     m_bCanDoTableFog  = (dwCaps&D3DPRASTERCAPS_FOGTABLE) &&
  546.                         ((dwCaps&D3DPRASTERCAPS_ZFOG) || (dwCaps&D3DPRASTERCAPS_WFOG))    
  547.                                                           ? TRUE : FALSE;
  548.     m_bCanDoVertexFog = (dwCaps&D3DPRASTERCAPS_FOGVERTEX) ? TRUE : FALSE;
  549.     m_bCanDoWFog      = (dwCaps&D3DPRASTERCAPS_WFOG)      ? TRUE : FALSE;
  550.  
  551.     // Update the UI checkbox states
  552.     ((CButton*)GetDlgItem(IDC_TABLEFOG))->EnableWindow(m_bCanDoTableFog);
  553.     ((CButton*)GetDlgItem(IDC_VERTEXFOG))->EnableWindow(m_bCanDoVertexFog);
  554.  
  555.     if( m_bCanDoWFog )
  556.         GetDlgItem(IDC_USINGWFOG)->SetWindowText( _T("Device using W-fog") );
  557.     else
  558.         GetDlgItem(IDC_USINGWFOG)->SetWindowText( _T("Device using Z-fog") );
  559.  
  560.     if( m_bUsingTableFog && m_bCanDoTableFog )
  561.     {
  562.         ((CButton*)GetDlgItem(IDC_VERTEXFOG))->SetCheck(FALSE);
  563.         ((CButton*)GetDlgItem(IDC_TABLEFOG))->SetCheck(TRUE);
  564.     }
  565.     else if( m_bCanDoVertexFog )
  566.     {
  567.         ((CButton*)GetDlgItem(IDC_VERTEXFOG))->SetCheck(TRUE);
  568.         ((CButton*)GetDlgItem(IDC_TABLEFOG))->SetCheck(FALSE);
  569.     }
  570.     else
  571.     {
  572.         ((CButton*)GetDlgItem(IDC_VERTEXFOG))->SetCheck(FALSE);
  573.         ((CButton*)GetDlgItem(IDC_TABLEFOG))->SetCheck(m_bCanDoTableFog);
  574.     }
  575.  
  576.     // Set up table or vertex mode, as appropiate
  577.     if( ((CButton*)GetDlgItem(IDC_TABLEFOG))->GetCheck() )
  578.         OnTableFog();
  579.     if( ((CButton*)GetDlgItem(IDC_VERTEXFOG))->GetCheck() )
  580.         OnVertexFog();
  581. }
  582.  
  583.  
  584.  
  585.  
  586. //-----------------------------------------------------------------------------
  587. // Name: OnInitialUpdate()
  588. // Desc: When the AppForm object is created, this function is called to
  589. //       initialize it. Here we getting access ptrs to some of the controls,
  590. //       and setting the initial state of some of them as well.
  591. //-----------------------------------------------------------------------------
  592. VOID CAppForm::OnInitialUpdate()
  593. {
  594.     // Update the UI
  595.     CFormView::OnInitialUpdate();
  596.     ((CSliderCtrl*)GetDlgItem( IDC_FOGSTART_SLIDER ))->SetRange(0,100,TRUE);
  597.     ((CSliderCtrl*)GetDlgItem( IDC_FOGSTART_SLIDER ))->SetPos(0);
  598.     ((CSliderCtrl*)GetDlgItem( IDC_FOGEND_SLIDER ))->SetRange(0,100,TRUE);
  599.     ((CSliderCtrl*)GetDlgItem( IDC_FOGEND_SLIDER ))->SetPos(100);
  600.     ((CSliderCtrl*)GetDlgItem( IDC_FOGDENSITY_SLIDER ))->SetRange(0,100,TRUE);
  601.     ((CSliderCtrl*)GetDlgItem( IDC_FOGDENSITY_SLIDER ))->SetPos(0);
  602.     ((CButton*)GetDlgItem( IDC_LORESTERRAIN ))->SetCheck(TRUE);
  603.     ((CButton*)GetDlgItem(IDC_VERTEXFOG))->SetCheck(TRUE);
  604.  
  605.     // Save static reference to the render window
  606.     m_hwndRenderWindow = GetDlgItem(IDC_RENDERVIEW)->GetSafeHwnd();
  607.  
  608.     // Register a class for a fullscreen window
  609.     WNDCLASS wndClass = { CS_HREDRAW | CS_VREDRAW, FullScreenWndProc, 0, 0, NULL,
  610.                           NULL, NULL, (HBRUSH)GetStockObject(WHITE_BRUSH), NULL,
  611.                           _T("Fullscreen Window") };
  612.     RegisterClass( &wndClass );
  613.  
  614.     // We create the fullscreen window (not visible) at startup, so it can
  615.     // be the focus window.  The focus window can only be set at CreateDevice
  616.     // time, not in a Reset, so ToggleFullscreen wouldn't work unless we have
  617.     // already set up the fullscreen focus window.
  618.     m_hwndRenderFullScreen = CreateWindow( _T("Fullscreen Window"), NULL,
  619.                                            WS_POPUP, CW_USEDEFAULT,
  620.                                            CW_USEDEFAULT, 100, 100,
  621.                                            GetTopLevelParent()->GetSafeHwnd(), 0L, NULL, 0L );
  622.  
  623.     // Note that for the MFC samples, the device window and focus window
  624.     // are not the same.
  625.     CD3DApplication::m_hWnd = m_hwndRenderWindow;
  626.     CD3DApplication::m_hWndFocus = m_hwndRenderFullScreen;
  627.     CD3DApplication::Create( AfxGetInstanceHandle() );
  628.  
  629.     // Update UI, and device's fog parameters
  630.     OnVertexFog();
  631.     UpdateUIForDeviceCapabilites();
  632.     SetFogParameters();
  633. }
  634.  
  635.  
  636.  
  637.  
  638. //----------------------------------------------------------------------------
  639. // Name: GenerateTerrainDisk()
  640. // Desc: Generates a trianglestrip for a disk
  641. //----------------------------------------------------------------------------
  642. HRESULT CAppForm::GenerateTerrainDisk( LPDIRECT3DDEVICE8 pd3dDevice, DWORD dwNumSegments,
  643.                                        FLOAT fScale )
  644. {
  645.     HRESULT hr;
  646.  
  647.     m_dwNumTerrainVertices = 2 * dwNumSegments * (dwNumSegments);
  648.  
  649.     // Destroy the old vertex buffer, if any
  650.     SAFE_RELEASE( m_pTerrainVB );
  651.  
  652.     // Create a vertex buffer
  653.     hr = pd3dDevice->CreateVertexBuffer( m_dwNumTerrainVertices*sizeof(FOGVERTEX),
  654.                                          D3DUSAGE_WRITEONLY, D3DFVF_FOGVERTEX,
  655.                                          D3DPOOL_MANAGED, &m_pTerrainVB );
  656.     if( FAILED(hr) )
  657.         return hr;
  658.  
  659.     FOGVERTEX* pVertices = NULL;
  660.     hr = m_pTerrainVB->Lock( 0, m_dwNumTerrainVertices*sizeof(FOGVERTEX),
  661.                              (BYTE**)&pVertices, 0 );
  662.     if( FAILED(hr) )
  663.         return hr;
  664.  
  665.     // Generate a spiralized trianglestrip
  666.     for( DWORD ring = 0; ring < dwNumSegments; ring++ )
  667.     {
  668.         for( DWORD seg=0; seg < dwNumSegments; seg++ )
  669.         {
  670.             FLOAT fTheta = (seg*2*D3DX_PI) / dwNumSegments;
  671.             FLOAT r0     = (ring + fTheta/(2*D3DX_PI))*fScale/dwNumSegments;
  672.             FLOAT r1     = r0 + fScale/dwNumSegments;
  673.  
  674.             FLOAT x   = (FLOAT)sin( fTheta );
  675.             FLOAT z   = (FLOAT)cos( fTheta );
  676.  
  677.             FLOAT y0  =  (FLOAT)sin(r0*z*z+r0*x*x);
  678.             FLOAT nx0 = -(FLOAT)cos(r0*z*z+r0*x*x)*r0*2*x;
  679.             FLOAT ny0 = 1.0f;
  680.             FLOAT nz0 = -(FLOAT)cos(r0*z*z+r0*x*x)*r0*2*z;
  681.  
  682.             FLOAT y1  =  (FLOAT)sin(r1*z*z+r1*x*x);
  683.             FLOAT nx1 = -(FLOAT)cos(r1*z*z+r1*x*x)*r1*2*x;
  684.             FLOAT ny1 = 1.0f;
  685.             FLOAT nz1 = -(FLOAT)cos(r1*z*z+r1*x*x)*r1*2*z;
  686.  
  687.             // Add two vertices to the strip at each step
  688.             pVertices->p.x = r0*x;
  689.             pVertices->p.y = y0;
  690.             pVertices->p.z = r0*z;
  691.             pVertices->n.x = nx0;
  692.             pVertices->n.y = ny0;
  693.             pVertices->n.z = nz0;
  694.             pVertices->tu  = (r0*x)/fScale;
  695.             pVertices->tv  = (r0*z)/fScale;
  696.             pVertices++;
  697.  
  698.             pVertices->p.x = r1*x;
  699.             pVertices->p.y = y1;
  700.             pVertices->p.z = r1*z;
  701.             pVertices->n.x = nx1;
  702.             pVertices->n.y = ny1;
  703.             pVertices->n.z = nz1;
  704.             pVertices->tu  = (r1*x)/fScale;
  705.             pVertices->tv  = (r1*z)/fScale;
  706.             pVertices++;
  707.         }
  708.     }
  709.  
  710.     m_pTerrainVB->Unlock();
  711.  
  712.     return S_OK;
  713. }
  714.  
  715.  
  716.  
  717.  
  718. //----------------------------------------------------------------------------
  719. // Name: GenerateColumn()
  720. // Desc: Generates a trianglestrip for a column
  721. //----------------------------------------------------------------------------
  722. HRESULT CAppForm::GenerateColumn( LPDIRECT3DDEVICE8 pd3dDevice, DWORD dwNumSegments,
  723.                                   FLOAT fRadius, FLOAT fHeight )
  724. {
  725.     HRESULT hr;
  726.  
  727.     m_dwNumColumnVertices = 2 * (dwNumSegments+1);
  728.  
  729.     // Destroy the old vertex buffer, if any
  730.     SAFE_RELEASE( m_pColumnVB );
  731.  
  732.     // Create a vertex buffer
  733.     hr = pd3dDevice->CreateVertexBuffer( m_dwNumColumnVertices*sizeof(FOGVERTEX),
  734.                                          D3DUSAGE_WRITEONLY, D3DFVF_FOGVERTEX,
  735.                                          D3DPOOL_MANAGED, &m_pColumnVB );
  736.     if( FAILED(hr) )
  737.         return hr;
  738.  
  739.     FOGVERTEX* pVertices = NULL;
  740.     hr = m_pColumnVB->Lock( 0, m_dwNumColumnVertices*sizeof(FOGVERTEX),
  741.                              (BYTE**)(&pVertices), 0 );
  742.     if( FAILED(hr) )
  743.         return hr;
  744.  
  745.     // Generate a trianglestrip
  746.     for( DWORD seg=0; seg<=dwNumSegments; seg++ )
  747.     {
  748.         FLOAT fTheta = (2*D3DX_PI*seg)/dwNumSegments;
  749.         FLOAT nx     = (FLOAT)sin(fTheta);
  750.         FLOAT nz     = (FLOAT)cos(fTheta);
  751.         FLOAT r      = fRadius;
  752.         FLOAT u      = (1.0f*seg)/dwNumSegments;
  753.  
  754.         // Add two vertices to the strip at each step
  755.         pVertices->p.x = r*nx;
  756.         pVertices->p.y = fHeight;
  757.         pVertices->p.z = r*nz;
  758.         pVertices->n.x = nx;
  759.         pVertices->n.y = 0;
  760.         pVertices->n.z = nz;
  761.         pVertices->tu  = u;
  762.         pVertices->tv  = 1;
  763.         pVertices++;
  764.  
  765.         pVertices->p.x = r*nx;
  766.         pVertices->p.y = -1;
  767.         pVertices->p.z = r*nz;
  768.         pVertices->n.x = nx;
  769.         pVertices->n.y = 0;
  770.         pVertices->n.z = nz;
  771.         pVertices->tu  = u;
  772.         pVertices->tv  = 0;
  773.         pVertices++;
  774.     }
  775.  
  776.     m_pColumnVB->Unlock();
  777.  
  778.     return S_OK;
  779. }
  780.  
  781.  
  782.  
  783.  
  784. //-----------------------------------------------------------------------------
  785. // Name: CAppForm::OneTimeSceneInit()
  786. // Desc: Called during initial app startup, this function performs all the
  787. //       permanent initialization.
  788. //-----------------------------------------------------------------------------
  789. HRESULT CAppForm::OneTimeSceneInit()
  790. {
  791.     return S_OK;
  792. }
  793.  
  794.  
  795.  
  796.  
  797. //-----------------------------------------------------------------------------
  798. // Name: CAppForm::FrameMove()
  799. // Desc: Called once per frame, the call is the entry point for animating
  800. //       the scene.
  801. //-----------------------------------------------------------------------------
  802. HRESULT CAppForm::FrameMove()
  803. {
  804.     // Move the camera along an ellipse
  805.     D3DXVECTOR3 from( 50*sinf(m_fTime/2), 5.0f, 60*cosf(m_fTime/2) );
  806.     D3DXVECTOR3 at( 50*sinf(m_fTime/2+1.5f), 4.0f, 60*cosf(m_fTime/2+1.5f) );
  807.     D3DXVECTOR3 up( 0.0f, 1.0f, 0.0f );
  808.  
  809.     D3DXMATRIX matView;
  810.     D3DXMatrixLookAtLH( &matView, &from, &at, &up );
  811.     m_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );
  812.     return S_OK;
  813. }
  814.  
  815.  
  816.  
  817.  
  818. //-----------------------------------------------------------------------------
  819. // Name: CAppForm::Render()
  820. // Desc: Called once per frame, the call is the entry point for 3d
  821. //       rendering. This function sets up render states, clears the
  822. //       viewport, and renders the scene.
  823. //-----------------------------------------------------------------------------
  824. HRESULT CAppForm::Render()
  825. {
  826.     // Clear the viewport
  827.     m_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,
  828.                        m_dwFogColor, 1.0f, 0L );
  829.  
  830.     m_pd3dDevice->SetRenderState( D3DRS_FOGENABLE, TRUE );
  831.     m_pd3dDevice->SetRenderState( D3DRS_FOGCOLOR,  m_dwFogColor );
  832.  
  833.     m_pd3dDevice->SetRenderState( D3DRS_FOGSTART,   FtoDW(m_fFogStartValue) );
  834.     m_pd3dDevice->SetRenderState( D3DRS_FOGEND,     FtoDW(m_fFogEndValue) );
  835.     m_pd3dDevice->SetRenderState( D3DRS_FOGDENSITY, FtoDW(m_fFogDensity) );
  836.  
  837.     if( m_bUsingTableFog )
  838.     {
  839.         m_pd3dDevice->SetRenderState( D3DRS_FOGVERTEXMODE,  D3DFOG_NONE );
  840.         m_pd3dDevice->SetRenderState( D3DRS_FOGTABLEMODE,   m_dwFogMode );
  841.     }
  842.     else
  843.     {
  844.         m_pd3dDevice->SetRenderState( D3DRS_FOGTABLEMODE,   D3DFOG_NONE );
  845.         m_pd3dDevice->SetRenderState( D3DRS_FOGVERTEXMODE,  m_dwFogMode );
  846.         m_pd3dDevice->SetRenderState( D3DRS_RANGEFOGENABLE, m_bRangeBasedFog );
  847.     }
  848.  
  849.     // Begin the scene
  850.     if( SUCCEEDED( m_pd3dDevice->BeginScene() ) )
  851.     {
  852.         // Reset the world matrix
  853.         D3DXMATRIX matWorld;
  854.         D3DXMatrixIdentity( &matWorld );
  855.         m_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
  856.  
  857.         // Draw the terrain
  858.         m_pd3dDevice->SetVertexShader( D3DFVF_FOGVERTEX );
  859.         m_pd3dDevice->SetStreamSource( 0, m_pTerrainVB, sizeof(FOGVERTEX) );
  860.         m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP,
  861.                                    0, m_dwNumTerrainVertices-2 );
  862.  
  863.         // Draw the columns
  864.         for( DWORD i=0; i<20; i++ )
  865.         {
  866.             FLOAT tx = (i%10)*20.0f - 100.0f;
  867.             FLOAT ty =  0.0f;
  868.             FLOAT tz = (i<=10) ? 40.0f : -40.0f;
  869.  
  870.             D3DXMatrixTranslation( &matWorld, tx, ty, tz );
  871.             m_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
  872.  
  873.             m_pd3dDevice->SetVertexShader( D3DFVF_FOGVERTEX );
  874.             m_pd3dDevice->SetStreamSource( 0, m_pColumnVB, sizeof(FOGVERTEX) );
  875.             m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP,
  876.                                          0, m_dwNumColumnVertices-2 );
  877.         }
  878.  
  879.         // End the scene.
  880.         m_pd3dDevice->EndScene();
  881.     }
  882.  
  883.     return S_OK;
  884. }
  885.  
  886.  
  887.  
  888.  
  889. //-----------------------------------------------------------------------------
  890. // Name: CAppForm::InitDeviceObjects()
  891. // Desc: Initialize scene objects.
  892. //-----------------------------------------------------------------------------
  893. HRESULT CAppForm::InitDeviceObjects()
  894. {
  895.     // Get the device caps
  896.     D3DCAPS8 d3dCaps;
  897.     m_pd3dDevice->GetDeviceCaps( &d3dCaps );
  898.  
  899.     if( d3dCaps.RasterCaps & D3DPRASTERCAPS_WFOG )
  900.         m_bDeviceUsesWFog = TRUE;
  901.     else
  902.         m_bDeviceUsesWFog = FALSE;
  903.  
  904.     // Create the floor texture
  905.     if( FAILED( D3DUtil_CreateTexture( m_pd3dDevice, _T("SeaFloor.bmp"),
  906.                                        &m_pFloorTexture, D3DFMT_R5G6B5 ) ) )
  907.         return E_FAIL;
  908.  
  909.     // Generate some geometry for the app
  910.     if( m_bHiResTerrain )
  911.         GenerateTerrainDisk( m_pd3dDevice, 80, 100.0f );
  912.     else
  913.         GenerateTerrainDisk( m_pd3dDevice, 5, 100.0f );
  914.     GenerateColumn( m_pd3dDevice, 30, 1.0f, 10.0f );
  915.  
  916.     return S_OK;
  917. }
  918.  
  919.  
  920.  
  921.  
  922. //-----------------------------------------------------------------------------
  923. // Name: CAppForm::RestoreDeviceObjects()
  924. // Desc: Initialize scene objects.
  925. //-----------------------------------------------------------------------------
  926. HRESULT CAppForm::RestoreDeviceObjects()
  927. {
  928.     // Set up the object material
  929.     D3DMATERIAL8 mtrl;
  930.     D3DUtil_InitMaterial( mtrl, 1.0f, 1.0f, 1.0f );
  931.     m_pd3dDevice->SetMaterial( &mtrl );
  932.     m_pd3dDevice->SetRenderState( D3DRS_AMBIENT,  0x44444444 );
  933.  
  934.     // Set up a texture
  935.     m_pd3dDevice->SetTexture( 0, m_pFloorTexture );
  936.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
  937.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
  938.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_MODULATE );
  939.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
  940.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
  941.  
  942.     m_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
  943.  
  944.     // Set the transform matrices
  945.     D3DXMATRIX matWorld, matProj;
  946.     D3DXMatrixIdentity( &matWorld );
  947.     D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4.0f, 1.0f, NEAR_PLANE, FAR_PLANE );
  948.     m_pd3dDevice->SetTransform( D3DTS_WORLD,      &matWorld );
  949.     m_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
  950.  
  951.     // Set up the light
  952.     D3DLIGHT8 light;
  953.     D3DUtil_InitLight( light, D3DLIGHT_POINT, 0.0f, 50.0f, 0.0f );
  954.     light.Attenuation0 =  0.1f;
  955.     light.Range        = 200.0f;
  956.     m_pd3dDevice->SetLight( 0, &light );
  957.     m_pd3dDevice->LightEnable( 0, TRUE );
  958.     m_pd3dDevice->SetRenderState( D3DRS_LIGHTING,    TRUE );
  959.  
  960.     m_pd3dDevice->SetRenderState( D3DRS_ZENABLE,            TRUE );
  961.     m_pd3dDevice->SetRenderState( D3DRS_DITHERENABLE,       TRUE );
  962.     m_pd3dDevice->SetRenderState( D3DRS_SPECULARENABLE,     FALSE );
  963.  
  964.     return S_OK;
  965. }
  966.  
  967.  
  968.  
  969.  
  970. //-----------------------------------------------------------------------------
  971. // Name: CAppForm::InvalidateDeviceObjects()
  972. // Desc: Called when the device-dependent objects are about to be lost.
  973. //-----------------------------------------------------------------------------
  974. HRESULT CAppForm::InvalidateDeviceObjects()
  975. {
  976.     return S_OK;
  977. }
  978.  
  979.  
  980.  
  981.  
  982. //-----------------------------------------------------------------------------
  983. // Name: CAppForm::DeleteDeviceObjects()
  984. // Desc: Called when the app is exiting, or the device is being changed,
  985. //       this function deletes any device dependent objects.
  986. //-----------------------------------------------------------------------------
  987. HRESULT CAppForm::DeleteDeviceObjects()
  988. {
  989.     SAFE_RELEASE( m_pColumnVB );
  990.     SAFE_RELEASE( m_pTerrainVB );
  991.     SAFE_RELEASE( m_pFloorTexture );
  992.     return S_OK;
  993. }
  994.  
  995.  
  996.  
  997.  
  998. //-----------------------------------------------------------------------------
  999. // Name: CAppForm::FinalCleanup()
  1000. // Desc: Called before the app exits, this function gives the app the chance
  1001. //       to cleanup after itself.
  1002. //-----------------------------------------------------------------------------
  1003. HRESULT CAppForm::FinalCleanup()
  1004. {
  1005.     return S_OK;
  1006. }
  1007.  
  1008.  
  1009.  
  1010.  
  1011. //-----------------------------------------------------------------------------
  1012. // Name: CAppForm::ConfirmDevice()
  1013. // Desc: Called during device intialization, this code checks the device
  1014. //       for some minimum set of capabilities
  1015. //-----------------------------------------------------------------------------
  1016. HRESULT CAppForm::ConfirmDevice( D3DCAPS8* pCaps, DWORD dwBehavior, 
  1017.                                  D3DFORMAT Format )
  1018. {
  1019.     if( pCaps->RasterCaps & D3DPRASTERCAPS_FOGVERTEX )
  1020.         return S_OK;
  1021.  
  1022.     return E_FAIL;
  1023. }
  1024.  
  1025.  
  1026.  
  1027.  
  1028. //-----------------------------------------------------------------------------
  1029. // Name: SetFogParameters()
  1030. // Desc: Sets the apps parameters for rendering the scene
  1031. //-----------------------------------------------------------------------------
  1032. VOID CAppForm::SetFogParameters()
  1033. {
  1034.     m_fFogStartValue = ( m_fFogStartSlider*(FAR_PLANE-NEAR_PLANE) ) + NEAR_PLANE;
  1035.     m_fFogEndValue   = ( m_fFogEndSlider*(FAR_PLANE-NEAR_PLANE) ) + NEAR_PLANE;
  1036.  
  1037.     // Set fog start and end values for table (pixel) fog mode on devices that
  1038.     // do not use WFOG. These devices expect fog between 0.0 and 1.0.
  1039.     if( (FALSE==m_bDeviceUsesWFog) && (TRUE==m_bUsingTableFog) )
  1040.     {
  1041.         m_fFogStartValue = m_fFogStartSlider;
  1042.         m_fFogEndValue   = m_fFogEndSlider;
  1043.     }
  1044.  
  1045.     // Adjust terrain if necessary
  1046.     if( m_bHiResTerrainOld != m_bHiResTerrain )
  1047.     {
  1048.         m_bHiResTerrainOld  = m_bHiResTerrain;
  1049.  
  1050.         if( m_bHiResTerrain )
  1051.             GenerateTerrainDisk( m_pd3dDevice, 80, 100.0f );
  1052.         else
  1053.             GenerateTerrainDisk( m_pd3dDevice, 5, 100.0f );
  1054.     }
  1055. }
  1056.